package cn.tworice.cryption.service.impl;

import cn.tworice.cryption.service.CryptService;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Base64;

/**
 * 国密SM4加密解密实现
 */
public class SM4ServiceImpl implements CryptService {
    static {
        // 注册Bouncy Castle Provider
        Security.addProvider(new BouncyCastleProvider());
    }

    private static final String ALGORITHM_NAME = "SM4";
    private static final String TRANSFORMATION = "SM4/CBC/PKCS7Padding";
    private static final int IV_LENGTH = 16; // SM4块大小为16字节
    private static final int KEY_LENGTH = 16; // SM4密钥长度为16字节
    private static final String PROVIDER = "BC";
    private static final String IV="1234567890123456";

    private final SecretKeySpec secretKey;

    public SM4ServiceImpl(String key) {
        if (key.trim().length() != KEY_LENGTH) {
            throw new IllegalArgumentException("SM4密钥必须为16字节");
        }
        this.secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), ALGORITHM_NAME);
    }

    @Override
    public String encrypt(String input) {
        try {
            IvParameterSpec ivParameter = new IvParameterSpec(IV.getBytes(StandardCharsets.UTF_8));
            Cipher cipher = Cipher.getInstance(TRANSFORMATION, PROVIDER);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameter);
            byte[] encrypted = cipher.doFinal(input.getBytes(StandardCharsets.UTF_8));
            return Base64.getEncoder().encodeToString(encrypted);
        } catch (Exception e) {
            throw new RuntimeException("加密失败", e);
        }
    }

    @Override
    public String decrypt(String input) {
        try {
            byte[] encryptedData = Base64.getDecoder().decode(input);

            IvParameterSpec ivParameter = new IvParameterSpec(IV.getBytes(StandardCharsets.UTF_8));

            Cipher cipher = Cipher.getInstance(TRANSFORMATION, PROVIDER);
            cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameter);
            byte[] decrypted = cipher.doFinal(encryptedData);

            return new String(decrypted, StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new RuntimeException("解密失败", e);
        }
    }

    private byte[] generateIv() {
        byte[] iv = new byte[IV_LENGTH];
        new SecureRandom().nextBytes(iv);
        return iv;
    }
}
